package testjeu;

import java.util.ArrayList;

import org.newdawn.slick.SlickException;


/**
 * Gestionnaire des balles ( missiles )
 * @author YoTsumi
 * @see Balle
 */
public class Balles extends Jeu implements Constantes {
    
    
    private map laMap;
    
    private ArrayList<TankEnnemi> tankE= new ArrayList<TankEnnemi>();
    private ArrayList<Mine>       mineE = new ArrayList<Mine>();
    
    private ArrayList<TankEnnemi> EnnemisDétruits = new ArrayList<TankEnnemi>();
    private ArrayList<Mine> MinesDétruites = new ArrayList<Mine>();
    
    private ArrayList<Balle> lesBalles = new ArrayList<Balle>();
    

    
    /**
     * Constructeur : initialise le système de gestion de balles
     * @param tank      Liste des tanks
     * @param mine      Liste des mines
     * @param lamap     Map en cours
     */
    public Balles(ArrayList<TankEnnemi> tank, ArrayList<Mine> mine, map lamap) {
        this.laMap=lamap;
        this.tankE=tank;
        this.mineE=mine;
    }
    
    /**
     * Ajoute une balle au gestionnaire
     * 
     * @param colTank   Colone du tank qui tire
     * @param ligTank   Ligne du tank qui tire
     * @param angle     Angle que doit adopter la balle
     * @throws org.newdawn.slick.SlickException
     */
    public void ajouter(int colTank, int ligTank, int angle) throws SlickException {
        lesBalles.add(new Balle(colTank, ligTank, angle, false));

        debug("Nouvelle balle : "+angle);
    }
    
    /**
     * Ajoute une balle au gestionnaire
     * 
     * @param colTank   Colone du tank qui tire
     * @param ligTank   Ligne du tank qui tire
     * @param angle     Angle que doit adopter la balle
     * @param estEnnemi Si Vrai, alors la balle provient d'un tank Ennemi
     * @throws org.newdawn.slick.SlickException
     */   
    public void ajouter(int colTank, int ligTank, int angle, boolean estEnnemi) throws SlickException {
        lesBalles.add(new Balle(colTank, ligTank, angle, estEnnemi));
    }

    /**
     * Dessine les balles
     */
    public void dessiner() {
        for (Balle b:lesBalles) {
            b.dessiner();
        }
    }
    
    /**
     * Met à jour la position des balles, les détruits si nécessaire, et retourne les coordonnées des ennemis détruits
     * 
     * @param delta : Delta de l'update
     * @param colTank : Colone actuelle du tank
     * @param ligTank : Ligne actuelle du tank
     * @return Vrai si notre tank est détruit, faux sinon
     * @throws org.newdawn.slick.SlickException
     */
     public boolean update(int delta, int colTank, int ligTank/*, int angTank*/) throws SlickException {
       ArrayList<Balle> removeMe = new ArrayList<Balle>();
       EnnemisDétruits.clear();
       MinesDétruites.clear();
       
       int col, lig/*, lastCol, lastLig*/;
       
       // Parcours des balles
       for (Balle b:lesBalles) {
           int[]coord=b.coord();
           col=cases.pxlToCol(coord[0]);  lig=cases.pxlToLig(coord[1]);
           
           boolean boom=false;
           
           // La balle détruit-elle notre tank => Cas basique
           if (b.estEnnemi() && col==colTank && lig==ligTank) {
        	   lesBalles.remove(b); // Supprime la balle
        	   return true;  		// Retourne vrai car notre tank est touché
           }
       
           if (!b.estEnnemi()) {
        	   
	           // On recherche si la balle touche un tank  [Faire un while pluto !] [Bug : peut toucher plusieurs tank d'affilés ?]
	           for (TankEnnemi t : tankE ) {
	               if (t.estEnVie() && t.col()==col && t.lig()==lig) {
	                   removeMe.add(b); // On supprime la balle
	                   EnnemisDétruits.add(t);  // On ajoute le tank à la liste des tank détruits
	                   boom=true;
	               }
	           }
	           
	           // On recherche si la balle touche une mine
	           if (!boom) {
	               for (Mine m : mineE) {
	                   if (m.estEnVie() && m.col()==col && m.lig()==lig) {
	                       removeMe.add(b);
	                       MinesDétruites.add(m);
	                       boom=true;
	                   }
	               }
	           }
           }    
           
           
           if (!boom) {
                switch(laMap.action_Case(col, lig )) {

                   case Bloqué: 
                	   if (!b.estEnnemi()) removeMe.add(b); 
                   break;
                   
                   case Out: 
                      removeMe.add(b);  
                   break;

                   default:
                       b.update(delta);
                   break;
                }
           }
       }     
       
       lesBalles.removeAll(removeMe);
       return false;
    }
    
    /**
     * Vérifie si il y a au moins une balle en mouvement
     * @return  Vrai si au moins une balle existe
     */
    public boolean en_mouvement() {
        return lesBalles.size()>0;
    }

    
    public ArrayList<TankEnnemi> liste_ennemis_détruits() {
        return EnnemisDétruits;
    }
    
    public ArrayList<Mine> liste_mines_détruitees() {
        return MinesDétruites;
    }
}
